package com.its.us.web.service.sys;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.its.us.web.entity.sys.Role;
import com.its.us.web.entity.sys.User;
import com.its.us.web.mapper.sys.RoleMapper;
import com.its.us.web.service.sys.base.BasePageService;
import com.its.us.web.utils.ConstantsUtil;
import com.its.us.web.utils.Tree.TreeMenu;
import com.its.us.web.utils.Tree.TreeUtil;
import com.its.us.web.vo.sys.ResultBean;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author huguangjun
 * @className RoleService
 * @date 2020/12/3
 * @desc 9:07
 */
@Transactional(rollbackFor = Exception.class)
@Service
public class RoleService extends BasePageService<Role> {

    @Resource
    private RoleMapper roleMapper;


    /**
     * 角色列表
     *
     * @param map
     * @return
     */
    public IPage<Role> findByPage(Map<String, Object> map) {
        //设置查询条件
        QueryWrapper<Role> wrapper = new QueryWrapper();
        /*int page = Integer.parseInt(map.get("page").toString());
        int rows = Integer.parseInt(map.get("rows").toString());
        // 第一个参数：页码，第二个参数：每页多少行
        IPage<Role> pageInfo = new Page<>(page, rows);*/
        IPage<Role> pageInfo = initPage(map);
        wrapper.select("id", "role_name", "role_en");
        Iterator its = map.entrySet().iterator();
        // 封装
        while (its.hasNext()) {
            Map.Entry entry = (Map.Entry) its.next();
            String key = entry.getKey().toString();
            if (key.equals("roleName")) {
                wrapper.like("role_name", entry.getValue());
            }
        }
        IPage<Role> list = roleMapper.selectPage(pageInfo, wrapper.orderByDesc("id"));
        return list;
    }

    /**
     * save or update obj
     *
     * @param role
     */
    public ResultBean saveOrUpdate(Role role) {
        QueryWrapper<Role> wrapper = new QueryWrapper();
        // update
        if (StringUtils.isNotEmpty(role.getId())) {
            wrapper.eq("id", role.getId());
            Role obj = roleMapper.selectOne(wrapper);
            if (null != obj) {
                if (null != this.checkRoleEn(role)) {
                    // 数据已经存在
                    return new ResultBean("数据标识已存在.");
                } else {
                    Role entity = new Role();
                    if (StringUtils.isNotEmpty(role.getRoleEn()) && StringUtils.isNotEmpty(role.getRoleName())) {
                        if (!obj.getRoleEn().equals(role.getRoleEn())) {
                            entity.setRoleEn(role.getRoleEn());
                        }
                        if (!obj.getRoleName().equals(role.getRoleName())) {
                            entity.setRoleName(role.getRoleName());
                        }
                        // 参数：值和条件
                        roleMapper.update(entity, wrapper);
                        return new ResultBean("操作成功.");
                    }
                }
            } else {
                // 数据异常
                return new ResultBean("数据异常.");
            }
        } else {
            // insert
            Role obj = this.checkRoleEn(role);
            if (null != obj) {
                // 数据已经存在
                return new ResultBean("数据标识已存在.");
            } else {
                roleMapper.insert(role);
                return new ResultBean("操作成功.");
            }
        }
        return new ResultBean("数据标识已存在.");
    }

    /**
     * private method
     * for en find role obj
     *
     * @param role
     * @return
     */
    private Role checkRoleEn(Role role) {
        Role obj = null;
        QueryWrapper<Role> wrapper = new QueryWrapper();
        if (StringUtils.isNotEmpty(role.getRoleEn())) {
            wrapper.eq("role_en", role.getRoleEn());
            obj = roleMapper.selectOne(wrapper);
        }
        return obj;
    }

    /**
     * 详情
     *
     * @param id
     * @return
     */
    public Role findById(String id) {
        return roleMapper.selectById(id);
    }

    /**
     * 删除
     * 注意：不能删除自身
     *
     * @param ids
     * @return
     */
    public ResultBean deleteByIds(List<String> ids, String userName) throws Exception {
        List<Role> roles = roleMapper.getCurrentRoleIds(userName);
        // set has roleIds
        Set<String> hasIds = roles.stream().map(role -> role.getId()).collect(Collectors.toSet());
        // set params ids
        Set<String> paramIds = new HashSet<>(ids);
        // diff,because don't delete self
        Sets.SetView<String> diffSetIds = Sets.symmetricDifference(hasIds, paramIds);
        // set toList
        List<String> listIds = new ArrayList<>(diffSetIds);
        // filter has ids
        for (int i = 0; i < roles.size(); i++) {
            for (int j = 0; j < listIds.size(); j++) {
                if (roles.get(i).getId().equals(listIds.get(j))) {
                    listIds.remove(j);
                }
            }
        }
        // delete about sys_role
        if (listIds.size() > 0) {
            roleMapper.deleteBatchIds(listIds);
            // delete sys_user_role
            roleMapper.deleteUserRoleByRoleIds(listIds);
            // delete sys_role_menu
            roleMapper.deleteUserRoleMenuByRoleIds(listIds);
            // test transactional
            //System.out.println(1/0);
        }
        return new ResultBean("操作成功.");
    }

    /**
     * get all role for tree use
     *
     * @return
     * @throws Exception
     */
    public List<TreeMenu> getAllRole() throws Exception {
        List<Role> roles = roleMapper.getAllRole();
        List<TreeMenu> tree = TreeUtil.getRoleListForTree(roles);
        return tree;
    }

    /**
     * get role by userId
     * @return
     */
    public List<Role> getRoleByUserId(String userId) {
       return roleMapper.getRoleByUserId(userId);
    }

    /**
     * role auth menu
     * @param menuIds
     * @param roleId
     * @return
     */
    public ResultBean authMenu(List<String> menuIds, String roleId) throws Exception {
        if (menuIds.size() > 0) {
            // delete
            roleMapper.deleteRoleMenu(roleId);
            // add
            for(int i=0;i<menuIds.size();i++){
                // clear user role
                if(!menuIds.get(i).equals(ConstantsUtil.System.AUTH_NULL)){
                    roleMapper.insertRoleMenu(menuIds.get(i), roleId);
                }
            }
        }
        return new ResultBean("操作成功.");
    }
}
